package com.iflytek.http.impl;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;

import android.os.Bundle;
import android.os.Handler;

import com.iflytek.http.entity.HandledResult;
import com.iflytek.http.interfaces.Cachable;
import com.iflytek.http.interfaces.Handleable;
import com.iflytek.http.interfaces.OperationListener;

public abstract class AbstractOperation implements Runnable{
	public String mEncoding = "UTF-8";
	public String cacheKey;
	public Cachable cacher;
	protected long id;
	protected String url;
	protected Class<? extends Handleable> mHandlerClass;
	private Bundle extras;
	private Handler mHandler;
	private WeakReference<OperationListener> mCallback;
	private HttpOperationService mService;

	public AbstractOperation(int id, String url, Class<? extends Handleable> handlerClass, OperationListener listener){
		this.id = id;
		this.url = url;
		this.mHandlerClass = handlerClass;
		this.mCallback = new WeakReference(listener);
	}

	public void setExtras(Bundle bundle){
		extras = bundle;
	}

	public Bundle getExtras() {
		return extras;
	}

	public void setOperationListener(OperationListener listener)
	{
		mCallback = new WeakReference(listener);
	}

	protected abstract void handleOperation();

	protected HandledResult parse(String content, InputStream is) {
		Handleable parser = null;
		HandledResult result = null;
		try {
			parser = (Handleable)this.mHandlerClass.newInstance();
			if (parser == null)
				return null;
			if (is != null)
				result = parser.handle(is, getExtras());
			else if (content != null) {
				result = parser.handle(content, getExtras());
			}

			return result;
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			OperationListener listener = (OperationListener)this.mCallback.get();
			if (listener == null)
				return null;
			listener.onError(this.id, this.extras, e);
		} catch (InstantiationException e) {
			e.printStackTrace();
			OperationListener mListener = (OperationListener)this.mCallback.get();
			if (mListener == null)
				return null;
			mListener.onError(this.id, this.extras, e);
		}
		return result;
	}

	protected void sendExceptionMsg(final IOException e){
		if (mCallback.get() == null || mHandler == null){
			return;
		}
		mHandler.post(new Runnable(){
			public void run() {
				if (mCallback.get() != null){
					((OperationListener)mCallback.get()).onError(id, extras, e);
				}
			}
		});
	}

	protected void sendExceptionMsg(final Exception e){
		if (mCallback.get() == null || mHandler == null){
			return;
		}
		mHandler.post(new Runnable(){
			public void run() {
				if (mCallback.get() != null)
					((OperationListener)mCallback.get()).onError(id, extras, e);
			}
		});
	}

	protected void sendSuccessMsg(final HandledResult result){
		if ((this.mCallback.get() == null) || (this.mHandler == null))
			return;
		mHandler.post(new Runnable(){
			public void run() {
				if (mCallback.get() != null)
					((OperationListener)mCallback.get()).onResult(id, extras, result);
			}
		});
	}

	protected void sendNotOlayMsg(final int code, final String content) {
		if ((this.mCallback.get() == null) || (this.mHandler == null))
			return;
		mHandler.post(new Runnable(){
			public void run() {
				if (mCallback.get() != null)
					((OperationListener)mCallback.get()).onNotOkay(id, extras, code, content);
			}
		});
	}

	protected OperationListener getOperationListener()
	{
		return (OperationListener)this.mCallback.get();
	}

	void setServiceAndHandler(HttpOperationService service, Handler handler){
		mService = service;
		mHandler = handler;
	}

	public void run(){
		mService.increaseCounter();
		handleOperation();
		mService.decreaseCounter();
	}
}